package org.ucn.dmaa0914.temadesign.group2.modelLayer;
import java.util.HashSet;
import java.util.Iterator;

/**
 * The loan container class is responsible of containing all loans and perform lookups.
 * 
 * @author Kim Johannsen
 * @version 04-11-2014
 */
public class LoanContainer
{    
    HashSet<Loan> loanCollection;
    
    // Provide a singleton instance, as this class is only ment to be instantiated once per program.
    public static final LoanContainer instance = new LoanContainer();
    
    /**
     * Constructor
     */
    public LoanContainer()
    {
        loanCollection = new HashSet<Loan>();
    }
    
    /*
     * Adds a loan to the container, if it doesnt already exist
     * in the database.
     * 
     * @param p The loan to add
     * @return True if the loan was added. False if the loan was already added.
     */
    public boolean addLoan(Loan p)
    {
        return loanCollection.add(p);
    }
    
    /**
     * Checks whether this container has a loan.
     * 
     * @param p The loan to check for
     * @return True if this container has this loan. False if not.
     */
    public boolean containsLoan(Loan p)
    {
        return loanCollection.contains(p);
    }
    
    /**
     * Looks up a loan by it's id.
     * 
     * @param id The id of the loan to find.
     * @return The loan with the specified id, or null if the loan is not found.
     */
    public Loan getLoan(int id)
    {
        Iterator<Loan> i = loanCollection.iterator();
        
        while( i.hasNext() )
        {
            Loan p = i.next();
            
            if( p.getId() == id )
            {
                return p;
            }
        }
        
        return null;
    }
    
    /**
     * Finds all loans on the given person which fullfills the given criteria
     * 
     * @param p The person to get loans for. If p is null, all
     * persons are checked
     * @param active Criteria for searching for active loans
     * @param expired Criteria for searching for expired loans
     * @return A new loan set with active loans
     */
    public HashSet<Loan> findLoans(Person p, SearchCriteria active, SearchCriteria expired)
    {
        Iterator<Loan> i = loanCollection.iterator();
        HashSet<Loan> activeLoans = new HashSet<Loan>();
        
        while( i.hasNext() )
        {
            Loan l = i.next();
            
            // Use the discard method
            boolean useEntry = true;
            
            // Check if the loan has the wanted person
            if( !(l.getLoaner() == p || p == null) )
            {
                useEntry = false;
            }
            
            // Check if the loan is active when we want active loans
            if( active == SearchCriteria.Want )
            {
                if( !l.isActive() )
                {
                    useEntry = false;
                }
            }
            
            // Check if the loan is inactive when we want inactive loans
            if( active == SearchCriteria.WantOpposite )
            {
                if( l.isActive() )
                {
                    useEntry = false;
                }
            }
            
            // Check if the loan has expired when we want expired loans
            if( expired == SearchCriteria.Want )
            {
                if( !l.isExpired() )
                {
                    useEntry = false;
                }
            }
            
            // Check if the loan is not expired when we want nonexpired loans
            if( expired == SearchCriteria.WantOpposite )
            {
                if( l.isExpired() )
                {
                    useEntry = false;
                }
            }
            
            if( useEntry )
            {
                activeLoans.add(l);
            }
        }
        
        return activeLoans;
    }
    
    /**
     * Deletes a loan from the container if present
     * 
     * @param p The loan to delete
     */
    public void deleteLoan(Loan p)
    {
        loanCollection.remove(p);
    }
   
}
